#include <g-bios.h>
#include <core/cmd.h>
#include <sysconf.h>
#include <string.h>
#include <core/getopt.h>
#include <flash/part.h>
#include <core/bar.h>


struct EraseParam
{
	FLASH_HOOK_PARAM hParam;
	struct ProgressBar *pBar;
};


static void PartEraseUsage(void)
{
	printf("Usage: parterase <subcommands> [options <value>] [flags]\n"
			"options:\n"
			"  -p   \t\tset partition\n"
			"  -d   \t\tignore bad block\n"
//			"  -j   \t\tJffs2 file system.\n"
		  ); 
}

static int EraseProgress(struct Flash *pFlash, FLASH_HOOK_PARAM *pParam)
{
	struct EraseParam *pErInfo;

	pErInfo = MemToObj(pParam, struct EraseParam, hParam);

	SetVal(pErInfo->pBar, pParam->nBlockIndex);

	return 0;
}


static int main(int argc, char *argv[])
{
	int iRet, nDevNum;
	UINT32 ulSize, ulStart;
	UINT32 dwFlags = EDF_NORMAL;
	struct Flash *pFlash;
	struct Partition *pPart = NULL;
	UINT32 ch;
	struct EraseParam erInfo;
	char *optarg;
 
	while ((ch = getopt(argc, argv, "p:dh", &optarg)) != -1)
	{
		if ('\0' != argv[1][2])
		{
			printf("Invalid option: \"%s\"\n",argv[1]);
			printf("Try `%s -h` for more information.\n",argv[0]);
			return -EINVAL;
		}

		switch (ch)
		{
		case 'p':
			if(atoi(optarg, &nDevNum) < 0)
			{
		    	PartEraseUsage();
				goto L2;
			}

			pPart = GuPartOpen(nDevNum);
			if (NULL == pPart)
			{
				PartEraseUsage();
				goto L2;
			}

			break;

		case 'd':
			dwFlags |= EDF_ALLOWBB;

			break;
			
		case 'j':
#if 0
			if (pPart->pAttr->nPartType == PT_FS_JFFS2)
				dwFlags |= EDF_JFFS2;
#endif
			break;

		default:
			PartEraseUsage();

			goto L2;
		}
	}

	if (NULL == pPart)
	{
		pPart = GuPartOpenCur();
	}

	pFlash = pPart->pHost;

	ulStart = GuPartGetBase(pPart);
	ulSize  = GuPartGetSize(pPart);

	CreateProgressBar(&erInfo.pBar,
				ulStart >> pFlash->nEraseShift,
				(ulStart + ulSize - 1) >> pFlash->nEraseShift
				);

	GuFlashSetHook(pFlash, EraseProgress, &erInfo.hParam);

	iRet = GuFlashErase(pFlash, ulStart, ulSize, dwFlags);
	if (iRet < 0)
		printf("Erase error!~\n");

	DeleteBar(erInfo.pBar);
	
	GuPartSetImgInfo(pPart, "", 0);

	iRet = GuSysConfStore();
	if (iRet < 0)
		printf("Can not save configure information to flash");

	GuPartClose(pPart);

L2:
	return iRet;
}


INSTALL_APPLICATION(parterase, main, "erase the partition");

